package urldecode;


import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Decoder {
	List<String> li_decoded = new ArrayList<String>();
	DetectURLEncoding det = new DetectURLEncoding();
	String ENC = null;
	JSave saver = new JSave();
	
	//解密命令行字符串
	public List<String> Decode (String s) throws IOException {
		String s_trim = Cleaner.Clean(s);
		ENC = det.Detect(s_trim);
		li_decoded.add(URLDecoder.decode(s_trim, ENC));
		return li_decoded;
	}
	
	//解密文件
	public List<String> Decode (File input) throws IOException {
		String filename = input.getAbsoluteFile().toString();
		FileArrayProvider FR = new FileArrayProvider();
		String[] li_to_decode = FR.readLines(filename);
			
		for (String s : li_to_decode) {
			String s_trim = Cleaner.Clean(s);
			ENC = det.Detect(s_trim);
			String str_decoded = URLDecoder.decode(s_trim,ENC);
			li_decoded.add(str_decoded);
		}
		return li_decoded;
	}
	
	//解密文件，并输出到指定路径
	public File Decode (File input,File output) throws IOException {
		RandomAccessFile raf = new RandomAccessFile(input,"r");
		
		String line;
		while ((line = raf.readLine()) != null) {
			String s_trim = Cleaner.Clean(line);
			ENC = det.Detect(s_trim);
			saver.Add(output, URLDecoder.decode(s_trim,ENC));
		}
		
		raf.close();
		return output;

	}
	
	//解密文件，并输出到指定路径
	public File Decode (String inputFilename,String outputFileName) throws IOException {
		RandomAccessFile raf = new RandomAccessFile(inputFilename,"r");
		File outputFile = new File(outputFileName);
		String line;
		while ((line = raf.readLine()) != null) {
			String s_trim = Cleaner.Clean(line);
			ENC = det.Detect(s_trim);
			saver.Add(outputFileName, URLDecoder.decode(s_trim,ENC));
		}
		
		raf.close();
		return outputFile;

	}
	
	//解密数组列表
	public List<String> Decode (List<String> input) throws IOException {
			for (String s : input) {
				String s_trim = Cleaner.Clean(s);
				ENC = det.Detect(s_trim);
				li_decoded.add(URLDecoder.decode(s_trim, ENC));
			}
			return li_decoded;
	}
}

class Cleaner {
	static String Clean(String input) {
		Pattern pattern = Pattern.compile("(?<!%[a-fA-F0-9][a-fA-F0-9])%(\\p{Punct}|[a-zA-Z0-9])(\\p{Punct}|[a-zA-Z0-9])(?!%[a-fA-F0-9][a-fA-F0-9])");
		Matcher matcher = pattern.matcher(input);
		String s = matcher.replaceAll("");
		s = s.replaceAll("\\\\x", "%");
		s = s.replaceAll("%3A", ":");
		s = s.replaceAll("%3F", "?");
		s = s.replaceAll("%2F", "/");
		s = s.replaceAll("%3D", "=");
		s = s.replaceAll("%5C", "");
		s = s.replaceAll("\\$", "");
		s = input.replaceAll("(%[a-fA-F0-9][^a-fA-F0-9])|(%[^a-fA-F0-9])|(%$)|(%[a-fA-F0-9]$)", "");
		s = s.replaceAll("%00", "");
		return s;
	}
}
